home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr22 / at_clock.zip / FIXCLOCK.C < prev    next >
C/C++ Source or Header  |  1993-05-03  |  6KB  |  166 lines

  1. /*                               fixclock.c
  2.  *
  3.  * This program corrects the system time upon boot up. The system time is
  4.  * normally obtained from the cmos clock. This clock is crystal controlled
  5.  * but may exhibit an error of several minutes per month anyway. A knowledge
  6.  * of this error allows it to be compensated for and corrected.
  7.  *
  8.  * The program is designed to be called from the autoexec.bat file upon boot
  9.  * up. An example of the proper entry in the .bat file is as follows:
  10.  *
  11.  *          fixclock tz=cst6cdt 23:13:45 10-25-88 -213 L
  12.  *
  13.  * The first parameter sets the timezone. It consists of tz= followed by a
  14.  * three letter abbreviation of the standard timezone: pst, mst, cst, or est.
  15.  * This is followed by a number indicating the number of hours between the
  16.  * local time and GMT, followed by the abbreviation for daylight savings time,
  17.  * pdt, mdt, cdt, or edt if it is observed in your area. If it is not observed
  18.  * then don't append it. For instance, in parts of Indiana you would have a
  19.  * timezone parameter that looks like this: tz=cst6
  20.  *
  21.  * The next two entries are the time and date the cmos clock was properly set.
  22.  * These values are obtained from the clock statistics produced by the program
  23.  * clockerr, when the q parameter is used.
  24.  *
  25.  * The next entry is also obtained from the clock statistics report and is a
  26.  * signed integer representing the number of seconds gained or lost by the
  27.  * cmos clock per month. If the clock looses time then it is negative.
  28.  *
  29.  * The last entry on the command line determines whether the system will
  30.  * display local time or GMT. If you wish local time use an L here. For GMT
  31.  * use a G. If you choose the local option then the system will always display
  32.  * the local time and will correct for daylight savings time when it is in
  33.  * effect without any action on your part.
  34.  */
  35.  
  36. #include <stdlib.h>
  37. #include <time.h>
  38. #include <stdio.h>
  39. #include <ctype.h>
  40. #include <dos.h>
  41.  
  42. #define  MONTH  2419200.0                   /* Seconds in a month (28 days) */
  43. #define  LCL    1
  44. #define  GMT    0
  45.  
  46. void    main(int argc, char *argv[]);
  47. void    set_time(time_t *time, int local);
  48. time_t  clock_started(char *argv[]);
  49.  
  50. void  main(int argc, char *argv[])
  51.    {
  52.    int      i;
  53.    time_t   error, cmos_time, new_time;
  54.    double   elapsed;
  55.  
  56.    /*
  57.     * Check for proper number of command line arguments (5)
  58.     */
  59.    if(argc != 6)
  60.        {
  61.        puts("Incorrect Number Of Parameters...");
  62.        exit(0);
  63.        }
  64.  
  65.    /*
  66.     * The case of the first argument doesn't matter.
  67.     */
  68.    for(i=0; *(argv[1]+i); i++)
  69.       *(argv[1]+i)=toupper( *(argv[1]+i) );
  70.  
  71.    /*
  72.     * Put the time zone info which is the first argument, into the
  73.     * program environment. Next, set the global timezone variables
  74.     * to the specified values.
  75.     */
  76.    putenv(argv[1]);
  77.    tzset();
  78.  
  79.    /*
  80.     * time(&cmos_time) returns the time kept by the cmos clock, this is
  81.     * converted to seconds since the epoch. clock_started(argv) returns
  82.     * the time when the cmos clock was set, converted to seconds since
  83.     * the epoch, the time when the cmos clock was set is obtained from
  84.     * entries on the command line. The clock error is also obtained from
  85.     * the command line. new_time represents the corrected time in seconds
  86.     * since the epoch and is used to set the system time.
  87.     */
  88.    elapsed = time(&cmos_time) - clock_started(argv);
  89.    error = atoi(argv[4]);
  90.    new_time = cmos_time - elapsed * error/MONTH;
  91.    switch(toupper(*argv[5]))
  92.       {
  93.       case 'L':
  94.         /*
  95.          * Sets the correct local time as requested by the "L"
  96.          * on the command line.
  97.          */
  98.         set_time(&new_time, LCL);
  99.         break;
  100.  
  101.       case 'G':
  102.         /*
  103.          * Sets the correct Greenwich Mean Time by adding the
  104.          * value of the timezone variable to the corrected time.
  105.          */
  106.         new_time += timezone;
  107.         set_time(&new_time, GMT);
  108.       }
  109.    exit(0);
  110.    }
  111.  
  112. time_t clock_started(char *argv[])            /* clock value when first set */
  113.    {
  114.  
  115.    /*
  116.     * Command line values representing the time at which the cmos clock was
  117.     * set are retrieved and converted to integer values to fill the structure
  118.     * systime. This structure is then passed to mktime() so that the return
  119.     * value is a variable of type time_t.
  120.     */
  121.    struct tm   systime;
  122.    systime.tm_hour  =  atoi(argv[2]);
  123.    systime.tm_min   =  atoi(argv[2]+3);
  124.    systime.tm_sec   =  atoi(argv[2]+6);
  125.    systime.tm_mon   =  atoi(argv[3])-1;    /* MSOFT definition idiosyncracy */
  126.    systime.tm_mday  =  atoi(argv[3]+3);
  127.    systime.tm_year  =  atoi(argv[3]+6);
  128.    systime.tm_isdst =  0;           /* Command line value is standard time. */
  129.    return mktime(&systime);
  130.    }
  131.  
  132. void  set_time(time_t *time, int local)     /* Set the correct system time. */
  133.    {
  134.    struct tm         *time_date, *dst;
  135.    struct dostime_t  to_dostime;
  136.    struct dosdate_t  to_dosdate;
  137.  
  138.    /*
  139.     * Convert the correct time to a structure of type tm, then examine
  140.     * dst->is_dst to see if daylight savings time is in effect and observed
  141.     * and to see if local time format is desired. If so then add an hour to
  142.     * the correct time which otherwise is standard time.
  143.     */
  144.    dst = localtime(time);
  145.    if(dst->tm_isdst && daylight && local)
  146.       *time = *time + 3600;                 /* DST and local time in effect */
  147.  
  148.    /*
  149.     * The corrected time is converted to a structure of type tm. The elements
  150.     * of this structure are used to assign values to the structure to_dostime
  151.     * and to_dosdate. These two structures are then used to set the system
  152.     * date and time.
  153.     */
  154.    time_date = localtime(time);
  155.    to_dostime.hour = time_date->tm_hour;
  156.    to_dostime.minute = time_date->tm_min;
  157.    to_dostime.second = time_date->tm_sec;
  158.    to_dostime.hsecond = 50;                         /* In lieu of rounding. */
  159.    _dos_settime(&to_dostime);
  160.    to_dosdate.day = time_date->tm_mday;
  161.    to_dosdate.month = time_date->tm_mon + 1;
  162.    to_dosdate.year = time_date->tm_year + 1900;
  163.    to_dosdate.dayofweek = time_date->tm_wday;
  164.    _dos_setdate(&to_dosdate);
  165.    }
  166.